﻿// ---------------------------------------------------------------------------------------------
// <copyright file="CrmMetadataHelper.cs" company="Hiyoko">
//   Copyright (c) 2015 All Rights Reserved
// </copyright>
// <summary>
//   This helper class allows to manipulate metadatas from a Dynamics CRM organization.
// </summary>
// ---------------------------------------------------------------------------------------------

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using System;
using System.Collections.Generic;

namespace Hiyoko.DependenciesSorter
{
    public static class CrmMetadataHelper
    {
        #region Public methods

        /// <summary>
        /// Retrieves entities metadata using the specified Organization service.
        /// </summary>
        /// <param name="service">The Organization service.</param>
        /// <returns>The collection of entities nodes.</returns>
        public static EntityMetadata[] GetEntitiesMetadata(IOrganizationService service)
        {
            if (service == null)
            {
                throw new ApplicationException("An error occured: the provided argument <service> is null.");
            }

            var metadataRequest = new RetrieveAllEntitiesRequest
            {
                EntityFilters = EntityFilters.Relationships,
                RetrieveAsIfPublished = false
            };
            var metadataResponse = (RetrieveAllEntitiesResponse)service.Execute(metadataRequest);
            return metadataResponse.EntityMetadata;
        }

        /// <summary>
        /// Gets Many To One Dependencies
        /// </summary>
        /// <param name="entityMetadata">The entity metadata</param>
        /// <returns>The list of logical name dependencies.</returns>
        public static List<string> GetManyToOneDependencies(this EntityMetadata entityMetadata)
        {
            var dependencies = new List<string>();
            foreach (var relationshipMetadata in entityMetadata.ManyToOneRelationships)
            {
                var dependencyLogicalName = relationshipMetadata.ReferencedEntity.ToLowerInvariant();
                if (!dependencies.Contains(dependencyLogicalName) && !dependencyLogicalName.Equals("owner"))
                {
                    dependencies.Add(dependencyLogicalName);
                }
            }
            return dependencies;
        }

        #endregion Public methods
    }
}
